home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / smailsrc.zip / UUPC.ZIP / DCPSYS.C < prev    next >
Text File  |  1990-04-21  |  14KB  |  742 lines

  1. /*
  2.  *   8 space tabs for this file
  3.  */
  4.  
  5. /*
  6.     dcpsys.c
  7.  
  8.     Revised edition of dcp
  9.  
  10.     Stuart Lynne May/87
  11.  
  12.     Copyright (c) Richard H. Lamb 1985,    1986, 1987
  13.     Changes Copyright (c) Stuart Lynne 1987
  14.  
  15. */
  16.  
  17. /* "DCP" a uucp    clone. Copyright Richard H. Lamb 1985,1986,1987    */
  18.  
  19. /* Support routines */
  20.  
  21. #include "ndir.h"
  22.  
  23. #include "dcp.h"
  24.  
  25. #define    MAXLOGTRY   3
  26. #define    TIMEOUT        -1
  27.  
  28. #define    PROTOS    "g"        /* available protocoles */
  29.  
  30. Proto Protolst[] = {
  31.     'g', ggetpkt, gsendpkt, gopenpk, gclosepk,
  32.     '\0'};
  33.  
  34. #define    EOTMSG "\004\r\004\r"
  35.  
  36. procref    getpkt,    sendpkt, openpk, closepk;
  37.  
  38. static char *flds[60];
  39. static int kflds;
  40. static char proto[5];
  41. static char S_sysline[BUFSIZ], S_sysdevice[16],    S_sysspeed[16];
  42.  
  43. extern void wmsg();
  44. extern int rmsg();
  45.  
  46. static void setproto();
  47. static int checktime();
  48.  
  49.  
  50. /****************************************/
  51. /*        Sub Systems        */
  52. /****************************************/
  53.  
  54. /*
  55.     g e    t s y s    t e m
  56.  
  57.     Process a systems file (L.sys) entry.
  58.     Null lines or lines    starting with '#' are comments.
  59. */
  60.  
  61. char getsystem()
  62. {
  63.     do {    /* flush to    next non-comment line */
  64.     if (fgets(S_sysline, BUFSIZ, fsys) == nil(char))
  65.         return 'A';    /* end-of-file */
  66.     } while ((*S_sysline == '\0') || (*S_sysline == '\n') || (*S_sysline == '#'));
  67.  
  68.     printmsg(8,    "sysline=\"%s\"", S_sysline);
  69.  
  70.     kflds = getargs(S_sysline, flds);
  71.     strcpy(rmtname, flds[FLD_REMOTE]);
  72.     strcpy(S_sysdevice,    flds[FLD_DEVICE]);
  73.     /* strcpy(type, flds[FLD_TYPE]); */
  74.     strcpy(S_sysspeed, flds[FLD_SPEED]);
  75.     strcpy(proto, flds[FLD_PROTO]);
  76.  
  77.     if (debuglevel >= 4) {
  78.     int i;
  79.     for (i = FLD_EXPECT; i < kflds;    i += 2)
  80.         printmsg(6,    "expect    [%02d]:\t%s\nsend   [%02d]:\t%s",
  81.         i, flds[i], i +    1, flds[i + 1]);
  82.     }
  83.  
  84.     printmsg(2,    "remote=%s, call-time=%s,", rmtname, flds[FLD_CCTIME]);
  85.     printmsg(2,    "device=%s, speed=%s, protocol=%s",
  86.     S_sysdevice, S_sysspeed, proto);
  87.     fwork = nil(FILE);
  88.     if (checktime(flds[FLD_CCTIME]) && (
  89.     equal(Rmtname, "all") ||
  90.     equaln(Rmtname,    rmtname, 7) ||
  91.     (equal(Rmtname, "any") && scandir(rmtname) == 'S'))) {
  92.  
  93.     if (fwork != nil(FILE))    /* in case matched with    scandir    */
  94.         fclose(fwork);
  95.     return 'S';    /* startup this    system */
  96.  
  97.     } else
  98.     return 'G';
  99.  
  100. } /*getsystem*/
  101.  
  102.  
  103. /*
  104.     c h    e c k n    a m e
  105.  
  106.     Look up a system name in our systems (L.sys) file.
  107.     Only the first 7 characters    of a system name is significant.
  108. */
  109.  
  110. static int checkname(name)
  111. char *name;
  112. {
  113.     FILE *ff;
  114.     char line[BUFSIZ];
  115.  
  116.     if ((ff = FOPEN(s_systems, "r", TEXT)) == nil(FILE))
  117.     return FAILED;
  118.  
  119.     while (fgets(line, BUFSIZ, ff) != nil(char)) {
  120.     printmsg(3, "checkname:    got '%s', want '%s'", line, name);
  121.     if (equaln(name, line, 7)) {
  122.         fclose(ff);
  123.         return OK;        /* OK, we like you */
  124.     }
  125.     }
  126.     fclose(ff);
  127.     return FAILED;  /* Who are you? */
  128.  
  129. } /*checkname*/
  130.  
  131.  
  132. /*
  133.     c h    e c k t    i m e
  134.  
  135.     Check if we    may make a call    at this    time
  136.     ***    to be implemented.  Again, didn't think    it crucial.
  137. */
  138.  
  139. static int checktime(xtime)
  140. char *xtime;
  141. {
  142.  
  143.     printmsg(2,    "checktime: %s", xtime);
  144.  
  145.     return TRUE;    /* OK, go to it */
  146.  
  147. } /*checktime*/
  148.  
  149.  
  150. /*
  151.     s y    s e n d
  152.  
  153.     End    UUCP session negotiation
  154. */
  155.  
  156. char sysend()
  157. {
  158.     char msg[80];
  159.  
  160.     msg[1] = '\0';
  161.     msgtime = 2    * MSGTIME;
  162.     /* while (msg[1] !=    'O') { */
  163.     wmsg("OOOOOO", TRUE);
  164.     if (rmsg(msg, TRUE) == TIMEOUT)
  165.         goto hang;
  166.     /*}*/
  167. hang:
  168.     wmsg("OOOOOO", TRUE);
  169.  
  170.     closeline();
  171.  
  172.     return (remote == MASTER) ?    'I' : 'A';
  173.  
  174. } /*sysend*/
  175.  
  176.  
  177. /*
  178.     w m    s g
  179.  
  180.     write a ^P type msg    to the remote uucp
  181. */
  182.  
  183. void wmsg(msg, synch)
  184. char *msg;
  185. int synch;
  186. {
  187.  
  188.     if (synch)
  189.     swrite("\0\020", 2);
  190.  
  191.     swrite(msg,    strlen(msg));
  192.  
  193.     if (synch)
  194.     swrite("\0", 1);
  195.  
  196. } /*wmsg*/
  197.  
  198.  
  199. /*
  200.     r m    s g
  201.  
  202.     read a ^P msg from UUCP
  203. */
  204.  
  205. int rmsg(msg, synch)
  206. char *msg;
  207. int synch;
  208. {
  209.     int    i;
  210.     char ch;
  211.  
  212.     /* flush until next    ^P */
  213.     if (synch)
  214.     do
  215.         if (sread(&ch, 1, msgtime) < 1)
  216.         return TIMEOUT;
  217.     while ((ch & 0x7f) != '\020');
  218.  
  219.     for    (i = 0;    (i < 132) && (ch != '\0'); ) {
  220.     if (sread(&ch, 1, msgtime) < 1)
  221.         return TIMEOUT;
  222.     ch &= 0x7f;
  223.     if (ch == '\r' || ch ==    '\n')
  224.         ch = '\0';
  225.     msg[i++] = ch;
  226.     }
  227.  
  228.     return strlen(msg);
  229.  
  230. } /*rmsg*/
  231.  
  232.  
  233. /*
  234.     s t    a r t u    p
  235. */
  236.  
  237. char startup()
  238. {
  239.     char msg[80];
  240.  
  241.     if (remote == MASTER) {
  242.  
  243.     msgtime    = 2 * MSGTIME;
  244.  
  245.     if (rmsg(msg, TRUE) == TIMEOUT)
  246.         return 'Y';
  247.     printmsg(2, "1st msg = %s", msg);
  248.     if (msg[5] == '=' && !equaln(&msg[6], rmtname, 7))
  249.         return 'Y';    /* wrong host */
  250.  
  251.     /* sprintf(msg,    "S%.7s -Q0 -x%d", nodename, debuglevel); */
  252.     /* -Q0 -x16 remote debuglevel set */
  253.     sprintf(msg, "S%.7s", nodename);
  254.     wmsg(msg, TRUE);
  255.  
  256.     if (rmsg(msg, TRUE) == TIMEOUT)
  257.         return 'Y';
  258.     printmsg(2, "2nd msg = %s", msg);
  259.     if (!equaln(&msg[1], "OK", 2))
  260.         return 'Y';
  261.  
  262.     if (rmsg(msg, TRUE) == TIMEOUT)
  263.         return 'Y';
  264.     printmsg(2, "3rd msg = %s", msg);
  265.     if (msg[0] != 'P' || (strchr(&msg[1], proto[0])    == nil(char))) {
  266.         wmsg("UN", TRUE);
  267.         return 'Y'; /* no common protocol */
  268.     } else {
  269.         sprintf(msg, "U%c",    proto[0]);
  270.         wmsg(msg, TRUE);
  271.     }
  272.     setproto(proto[0]);
  273.  
  274.     return 'D';
  275.  
  276.     } else {
  277.     char tmp1[20], tmp2[20];
  278.  
  279.     msgtime    = 2 * MSGTIME;
  280.  
  281.     sprintf(msg, "Shere=%s", nodename);
  282.     wmsg(msg, TRUE);
  283.  
  284.     if (rmsg(msg, TRUE) == TIMEOUT)
  285.         return 'Y';
  286.     sscanf(&msg[1], "%s %s %s", rmtname, tmp1, tmp2);
  287.     sscanf(tmp2, "-x%d", &debuglevel);
  288.     printmsg(1, "debuglevel    set to %d by remote", debuglevel);
  289.     printmsg(2, "1st msg from remote = %s",    msg);
  290.     if (checkname(rmtname))
  291.         return 'Y';
  292.  
  293.     wmsg("ROK", TRUE);
  294.  
  295.     sprintf(msg, "P%s", PROTOS);
  296.     wmsg(msg, TRUE);
  297.  
  298.     if (rmsg(msg, TRUE) == TIMEOUT)
  299.         return 'Y';
  300.     if (msg[0] != 'U' || (strchr(PROTOS, msg[1]) ==    nil(char)))
  301.         return 'Y';
  302.  
  303.     proto[0] = msg[1];
  304.     setproto(proto[0]);
  305.  
  306.     return 'R';
  307.  
  308.     }
  309.  
  310. } /*startup*/
  311.  
  312.  
  313. /*
  314.     s e    t p r o    t o
  315.  
  316.     set    the protocol to    be used
  317. */
  318.  
  319. static void setproto(wanted)
  320. char wanted;
  321. {
  322.     Proto   *tproto;
  323.  
  324.     for    (tproto    = Protolst;
  325.     tproto->type !=    '\0' &&    tproto->type !=    wanted;
  326.     tproto++) {
  327.     printmsg(3, "setproto: wanted '%c', have '%c'",    wanted,    tproto->type);
  328.     }
  329.     if (tproto->type ==    '\0') {
  330.     printmsg(0, "setproto: You said    I have it but I    cant find it!");
  331.     exit(1);
  332.     }
  333.     getpkt = tproto->a;
  334.     sendpkt = tproto->b;
  335.     openpk = tproto->c;
  336.     closepk = tproto->d;
  337.  
  338. } /*setproto*/
  339.  
  340.  
  341. #define    prefix(small,large) (equaln((small), (large), strlen(small)))
  342. #define    notin(str,log)        (strstr((log), (str)) == nil(char))
  343.  
  344. /*
  345.     e x    p e c t    s t r
  346. */
  347.  
  348. #define    MAXHIST    300
  349.  
  350. int expectstr(str, timeout)
  351. char *str;
  352. int timeout;
  353. {
  354.     static char    history[MAXHIST];
  355.  
  356.     char *rp = history;
  357.  
  358.     printmsg(1,    "wanted    %s", str);
  359.  
  360.     if (equal(str, "\"\""))    /* expects nothing */
  361.     return TRUE;
  362.  
  363.     *rp    = 0;
  364.     while (notin(str, history))    {
  365.     char ch;
  366.  
  367.     if (sread(&ch, 1, timeout) < 1)
  368.         return FALSE;
  369.  
  370.     if ((*rp = (ch & 0x7f))    != '\0')
  371.         rp++;
  372.     *rp = '\0';
  373.  
  374.     if (rp >= history + MAXHIST)
  375.         return FALSE;
  376.  
  377.     }
  378.     return TRUE;
  379.  
  380. } /*expectstr*/
  381.  
  382.  
  383. int writestr(s)
  384. register char *s;
  385. {
  386.     register char last;
  387.     int    nocr;
  388.     last = '\0';
  389.     nocr = FALSE;
  390.     while (*s) {
  391.     if (last == '\\') {
  392.         switch (*s)    {
  393.         case 'd':    /* delay */
  394.         case 'D':
  395.         sleep(2);
  396.         break;
  397.         case 'c':    /* don't output    CR at end of string */
  398.         case 'C':
  399.         nocr = TRUE;
  400.         break;
  401.         case 'r':    /* carriage return */
  402.         case 'R':
  403.         case 'm':
  404.         case 'M':
  405.         swrite("\r", 1);
  406.         break;
  407.         case 'n':    /* new line */
  408.         case 'N':
  409.         swrite("\n", 1);
  410.         break;
  411.         case 'b':    /* backspace */
  412.         case 'B':
  413.         swrite("\b", 1);
  414.         break;
  415.         case 't':    /* tab */
  416.         case 'T':
  417.         swrite("\t", 1);
  418.         break;
  419.         case 's':    /* space */
  420.         case 'S':
  421.         swrite(" ", 1);
  422.         break;
  423.         case 'z':    /* set serial port speed */
  424.         case 'Z':
  425.         SIOSpeed(++s);
  426.         while (*s != '\0' && *s    != '\\')
  427.             s++;
  428.         if (*s == '\\')
  429.             s++;
  430.         break;
  431.         default:    /* ordinary character */
  432.         swrite(s, 1);
  433.         }
  434.         last = '\0';
  435.     }
  436.     else if    (*s != '\\')    /* backslash */
  437.         swrite(s, 1);
  438.     else
  439.         last = *s;
  440.     s++;
  441.     }
  442.  
  443.     return nocr;
  444.  
  445. } /*writestr*/
  446.  
  447.  
  448. /*
  449.     s e    n d s t    r
  450.  
  451.     Send line of login sequence
  452. */
  453.  
  454. static void sendstr(str)
  455. char *str;
  456. {
  457.     printmsg(2,    "sending %s", str);
  458.  
  459.     if (equaln(str, "BREAK", 5)) {
  460.     int nulls;
  461.     nulls =    atoi(&str[5]);
  462.     if (nulls <= 0 || nulls    > 10)
  463.         nulls = 3;
  464.     ssendbrk(nulls);    /* send a break signal */
  465.     return;
  466.     }
  467.  
  468.     if (equal(str, "EOT")) {
  469.     swrite(EOTMSG, strlen(EOTMSG));
  470.     return;
  471.     }
  472.  
  473.     if (equal(str, "\"\""))
  474.     *str = '\0';
  475.  
  476.     if (!equal(str,""))    {
  477.     if (!writestr(str)) {
  478.         swrite("\r", 1);
  479.     }
  480.     } else
  481.     swrite("\r", 1);
  482.     return;
  483.  
  484. } /*sendstr*/
  485.  
  486.  
  487. /*
  488.     s e    n d e x    p e c t
  489. */
  490.  
  491. static int sendexpect(send, expect, timeout)
  492. char *send, *expect;
  493. int timeout;
  494. {
  495.  
  496.     sendstr(send);
  497.     return expectstr(expect, timeout);
  498.  
  499. } /*sendexpect*/
  500.  
  501.  
  502.  
  503. /*
  504.     d i    a l
  505. */
  506.  
  507. static int dial()
  508. {
  509.     char buf[4];
  510.  
  511.     if (!equal(flds[FLD_TYPE], "HAYES")) {
  512.     printmsg(0, "dial: unsupported dialer %s", flds[FLD_TYPE]);
  513.     return FALSE;
  514.     }
  515.  
  516.     printmsg(3,    "dial: calling host %s", rmtname);
  517.     if (openline(S_sysdevice, "2400"))
  518.     return FALSE;
  519.  
  520.     printmsg(0,    "hayes:    trying 2400");
  521.     if (sendexpect("ATZ", "OK",    2) != TRUE) {
  522.     sendexpect("\\d+++\\d",    "OK", 2);
  523.     if (sendexpect("ATZ", "OK", 2) != TRUE)    {
  524.         printmsg(0,    "hayes:    trying 1200");
  525.         SIOSpeed("1200");
  526.         if (sendexpect("ATZ", "OK",    2) != TRUE) {
  527.         sendexpect("\\d+++\\d",    "OK", 2);
  528.         if (sendexpect("ATZ", "OK", 2) != TRUE)
  529.             return FALSE;
  530.         }
  531.     }
  532.     }
  533.     printmsg(0,    "hayes:    got modem response");
  534.  
  535.     /*(sendstr("\\d\\dATS7=30");
  536.     expectstr("OK", 40);*/
  537.  
  538.     sendstr("\\d\\dATX4\\c");
  539.  
  540.     if (sendexpect(S_sysspeed, "CONNECT    ", 40) == TRUE)    {
  541.     printmsg(3, "hayes: got    CONNECT");
  542.  
  543.     if (sread(buf, 4, 4) ==    4) {
  544.         printmsg(3,    "hayes:    speed select %s", buf);
  545.         /* set speed appropriately */
  546.         SIOSpeed(buf);
  547.     }
  548.     return TRUE;
  549.     }
  550.     else
  551.     return FALSE;
  552.  
  553. } /*dial*/
  554.  
  555.  
  556. /*
  557.     c a    l l u p
  558.  
  559.     script processor - nothing fancy!
  560. */
  561.  
  562. char callup()
  563. {
  564.     char *exp, *alternate;
  565.     int    ok, i;
  566.  
  567.     printmsg(0,    "callup: calling host \"%s\"", rmtname);
  568.  
  569.     if (!equal(flds[FLD_TYPE], "DIR"))  {
  570.     if (dial() == FALSE)
  571.         return 'G';
  572.     }
  573.     else
  574.     if (openline(S_sysdevice, S_sysspeed))
  575.         return 'G';
  576.  
  577.     for    (i = FLD_EXPECT; i < kflds; i += 2) {
  578.  
  579.     exp = flds[i];
  580.     printmsg(2, "expecting %d of %d    \"%s\"", i, kflds, exp);
  581.  
  582.     ok = FALSE;
  583.     while (ok != TRUE) {
  584.  
  585.         alternate =    strchr(exp, '-');
  586.         if (alternate != nil(char))
  587.         *alternate++ = '\0';
  588.  
  589.         ok = expectstr(exp,    30);
  590.  
  591.         if (ok) {
  592.         printmsg(2, "got that");
  593.         break;
  594.         } else
  595.         printmsg(1, "got ???");
  596.  
  597.         if (alternate == nil(char))    {
  598.         printmsg(0, "LOGIN FAILED");
  599.         return 'Y';
  600.         }
  601.  
  602.         exp    = strchr(alternate, '-');
  603.         if (exp != nil(char))
  604.         *exp++ = '\0';
  605.  
  606.         printmsg(0,    "sending alternate");
  607.         sendstr(alternate);
  608.  
  609.     } /*while*/
  610.  
  611.     printmsg(2, "sending %d    of %d \"%s\"", i + 1, kflds, flds[i + 1]);
  612.     sleep(1);
  613.     sendstr(flds[i + 1]);
  614.  
  615.     } /*for*/
  616.  
  617.     return 'P';
  618.  
  619. } /*callup*/
  620.  
  621.  
  622. /*
  623.     s c    a n d i    r
  624.  
  625.     Scan spooling directory for    C.* files for the remote host (rmtname)
  626.  
  627.     returns:
  628.     A   - abort
  629.     Y   - can't open file
  630.     S   - ok
  631.     Q   - no files
  632. */
  633.  
  634. char scandir(remote)
  635. char *remote;
  636. {
  637.     char callpfx[40];
  638.     int    pfxlen;
  639.     DIR    *dirp;
  640.     struct direct *dp;
  641.  
  642.     if ((dirp =    opendir(spooldir)) == nil(DIR))    {
  643.     printmsg(0, "scandir: couldn't opendir() %s", spooldir);
  644.     return 'A';
  645.     }
  646.  
  647.     sprintf(callpfx, CALLFILE, remote);
  648.     pfxlen = strlen(callpfx);
  649.     printmsg(5,    "scandir: \"%s\"", callpfx);
  650.     while ((dp = readdir(dirp)) != nil(struct direct)) {
  651.     printmsg(10, " %s", dp->d_name);
  652.     if (equaln(callpfx, dp->d_name,    pfxlen)) {
  653.         printmsg(5,    "scandir: matched");
  654.         strcpy(workfile, dp->d_name);
  655.         closedir(dirp);
  656.         if ((fwork = FOPEN(workfile, "r", TEXT)) ==    nil(FILE))
  657.         return 'Y';
  658.         return 'S';
  659.     }
  660.     }
  661.     printmsg(5,    "scandir: not matched");
  662.     closedir(dirp);
  663.     return 'Q';
  664.  
  665. } /*scandir*/
  666.  
  667.  
  668. /*
  669.     x s    c a n d    i r
  670.  
  671.     Scan spooling directory for X.* files, for 'uuxqt'.
  672. */
  673.  
  674. char *xscandir(xname)
  675. char xname[];
  676. {
  677.     DIR    *dirp;
  678.     struct direct *dp;
  679.     int    pfxlen;
  680.  
  681.     if ((dirp =    opendir(spooldir)) == nil(DIR))    {
  682.     printmsg(0, "xscandir: couldn't    opendir() %s", spooldir);
  683.     return nil(char);
  684.     }
  685.  
  686.     printmsg(5,    "xscandir: \"%s\"", XQTPFX);
  687.     pfxlen = strlen(XQTPFX);
  688.     while ((dp = readdir(dirp))    != nil(struct direct)) {
  689.     printmsg(10, " %s",
  690.         dp->d_name,    XQTPFX);
  691.     if (equaln(XQTPFX, dp->d_name, pfxlen))    {
  692.         printmsg(5,    "xscandir: matched");
  693.         strcpy(xname, dp->d_name);
  694.         closedir(dirp);
  695.         return xname;
  696.     }
  697.     }
  698.     printmsg(5,    "xscandir: not matched");
  699.     closedir(dirp);
  700.     return nil(char);
  701.  
  702. } /*xscandir*/
  703.  
  704.  
  705. #if FALSE
  706.  
  707. /*
  708.     slowrite - comunication slow write.    needed for auto-baud modems
  709. */
  710.  
  711. void slowrite(st)
  712. char *st;
  713. {
  714.     int    len, j;
  715.     char c;
  716.  
  717.     len    = strlen(st);
  718.     printmsg(2,    "sent %s", st);
  719.     for    (j = 0;    j < len; j++) {
  720.     swrite(&st[j], 1);
  721.     ddelay(80000);
  722.     }
  723.  
  724. } /*slowrite*/
  725.  
  726.  
  727. /*
  728.     d d    e l a y
  729. */
  730.  
  731. void ddelay(dtime)
  732. int dtime;
  733. {
  734.     int    i, j;
  735.  
  736.     for    (i = 0;    i < dtime; i++)    {
  737.     }
  738.  
  739. } /*ddelay*/
  740.  
  741. #endif
  742.